import datetime
import socket
from concurrent.futures import ThreadPoolExecutor
from xml.dom.minidom import parse
import xml.dom.minidom

import redis


class UtcSignal(object):
    """
    连接socket消息服务器
    处理utc灯态数据
    """

    DIRECTION_DIC = {'1': '2_1', '2': '2_0', '3': '2_2', '4': '4_1', '5': '4_0', '6': '4_2', '7': '1_1',
                     '8': '1_0', '9': '1_2', '10': '3_1', '11': '3_0', '12': '3_2'}
    START_QUEUE_NAME = 'aibox:tsce_start'
    END_QUEUE_NAME = 'aibox:tsce_end'

    def __init__(self,ip,port,redisip,redisport=6379,db=0,decode_responses=True):
        """
        :param ip: 消息服务器ip
        :param port: 消息服务器端口 
        :param redisip: 
        :param redisport: 
        :param db: 
        :param decode_responses: 
        """
        self._client = socket.socket()
        self._client.connect((ip, port))
        self._executor = ThreadPoolExecutor(max_workers=3)
        pool = redis.ConnectionPool(host=redisip, decode_responses=decode_responses, 
                                    port=redisport, db=db)
        self._cache = redis.Redis(connection_pool=pool)

    def send(self, xmls):
        """
        发送xml
        :param xmls:
        :return:
        """
        by = xmls.encode('gb2312')  # 转为字节数组
        self._client.send(by)
        print("tcp发送成功")

    def sendr(self, xmlbw):
        by = xmlbw.encode('gb2312')  # 转为字节数组
        self._client.send(by)
        print("tcp发送成功")
        self.readone()

    def readone(self):
        data = ''
        while True:
            ret_bytes = self._client.recv(1024)
            ret_str = ret_bytes.decode('gb2312')
            data += ret_str
            if """</message>""" in ret_str:
                break
        print(data)
        self.get_xml_data(data)

    def readall(self):
        while True:
            self.readone()

    def sendw(self, xmlbw):
        by = xmlbw.encode('gb2312')  # 转为字节数组
        self._client.send(by)
        print("tcp发送成功")

        while True:
            ret_bytes = self._client.recv(1024)
            ret_str = ret_bytes.decode('gb2312')
            print(ret_str)

    def get_xml_data(self, data):
        """
        处理接收到的数据
        :param data:
        :return:
        """
        now_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        DOMTree = xml.dom.minidom.parseString(data)
        collection = DOMTree.documentElement
        # 首先判断xml类型，为SIGNALSTATUS时才处理
        type = collection.getElementsByTagName("type")[0].childNodes[0].nodeValue
        if type != 'SIGNALSTATUS':
            return
        lcid = collection.getElementsByTagName("lcid")[0].childNodes[0].nodeValue
        vehlamps = collection.getElementsByTagName("vehlamp")

        for vehlamp in vehlamps:
            index = vehlamp.attributes['index'].nodeValue
            status = vehlamp.childNodes[0].nodeValue
            # 暂时不考虑超出12的路口方向，只考虑东南西北四个正方向
            if int(index) > 12:
                continue
            dir = self.DIRECTION_DIC[index]
            key = lcid + '_' + dir
            if self._cache.hexists(self.START_QUEUE_NAME, key):
                last_dic = self._cache.hget(self.START_QUEUE_NAME, key)
                last_dic = last_dic.split('_')
                last_status = last_dic[1]
                if last_status == 'GREEN' and status == 'YELLOW':
                    greentime = last_dic[0] + '_' + now_time
                    self._cache.hset(self.END_QUEUE_NAME, key, greentime)
                    self._cache.hdel(self.START_QUEUE_NAME, key)
            elif status == 'GREEN':
                dic = now_time + '_' + status
                self._cache.hset(self.START_QUEUE_NAME, key, dic)

    def init_listen(self, utctype, lcid):
        listen_xml = f"""
                    <?xml version="1.0" encoding="GB2312"?>
                    <subscription System="ATMS" Ver="1.0">
                        <systemtype>UTC</systemtype>
                        <messagetype>NOTICE</messagetype>
                        <sourceIP></sourceIP>
                        <targetIP>{utctype}_{lcid}</targetIP>
                        <user>utc</user>
                        <password></password>
                    </subscription>
                    """
        start_xml = f"""
                    <?xml version="1.0" encoding="GB2312"?>
                    <message System="ATMS" Ver="1.0">
                        <systemtype>UTC</systemtype>
                        <messagetype>REQUEST</messagetype>
                        <sourceIP></sourceIP>
                        <targetIP>{utctype}</targetIP>
                        <user>utc</user>
                        <password></password>
                        <request>
                            <type>SIGNALSTART</type>
                            <id>{lcid}</id>
                        </request>
                    </message>"""
        self.send(listen_xml)
        self.send(start_xml)

    def start(self):
        self._executor.submit(self.readall)
